﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CotrobaieStatistics
{   
    /// <summary>
    /// Clasa care realizeaza constructia statisticilor pentru un produs dat
    /// </summary>
    class StatisticsRequest
    {
        private long productID;
        /// <summary>
        /// Creeaza un nou obiect care va face cereri la BD si va calcula statistici
        /// </summary>
        /// <param name="productID">ID-ul produsului, asa cum apare el in BD</param>
        public StatisticsRequest(long productID)
        {
            this.productID = productID;
        }
        private Price[] getPrices()
        {
            using(DataClassesDataContext db = new DataClassesDataContext())
            {
                var temp = from pret in db.Prices where pret.product_id == productID orderby pret.timestamp select pret ;
                return temp.ToArray<Price>();
            }
        }
        private Price[] getPrices(DateTime start)
        {
            using (DataClassesDataContext db = new DataClassesDataContext())
            {
                var temp = from pret in db.Prices where pret.product_id == productID && pret.timestamp >= start orderby pret.timestamp select pret;
                return temp.ToArray<Price>();
            }
        }
        private Price[] getPrices(DateTime start, DateTime end)
        {
            using (DataClassesDataContext db = new DataClassesDataContext())
            {
                var temp = from pret in db.Prices where pret.product_id == productID && pret.timestamp >= start && pret.timestamp <= end orderby pret.timestamp select pret;
                return temp.ToArray<Price>();
            }
        }
        /// <summary>
        /// Returneaza statistici pe toata perioada in care exista informatii despre produs
        /// </summary>
        /// <returns></returns>
        public StatisticsPair getStatistics()
        {
            Price[] result = getPrices();
            return BuildStatisticsPair(result);
        }
        /// <summary>
        /// Returneaza statistici incepand cu data specificata
        /// </summary>
        /// <param name="startDate">Data de inceput</param>
        /// <returns></returns>
        public StatisticsPair getStatistics(DateTime startDate)
        {
            Price[] result = getPrices(startDate);
            return BuildStatisticsPair(result);
        }
        /// <summary>
        /// Returneaza statistici incepand cu data de inceput si pana la data de sfarsit
        /// </summary>
        /// <param name="startDate">Data de inceput</param>
        /// <param name="endDate">Data de sfarsit</param>
        /// <returns></returns>
        public StatisticsPair getStatistics(DateTime startDate, DateTime endDate)
        {
            Price[] result = getPrices(startDate, endDate);
            return BuildStatisticsPair(result);
        }
        private Statistics BuildStatistics(Price[] arr)
        {
            double[] x = new double[arr.Length];
            double[] y = new double[arr.Length];
            double r = 0;
            for (int i = 0; i < arr.Length; i++)
            {
                y[i] = arr[i].price1 ?? 0;
                x[i] = (arr[i].timestamp - arr[0].timestamp).TotalDays;

            }
            RegressionLine line = new RegressionLine(x, y);
            for (int i = 1; i < arr.Length; i++)
            {
                r += ((arr[i].price1 - arr[i - 1].price1) / arr[i - 1].price1) ?? 0;
            }
            r /= arr.Length - 1;
            return new Statistics(arr[0].timestamp, arr[arr.Length - 1].timestamp, line, r);
        }
        private StatisticsPair BuildStatisticsPair(Price[] result)
        {
            Statistics amazon = null;
            Statistics ebay = null;
            if (result.Count<Price>(x => x.site_id == 1) >= 2) //nu au sens chestiile astea pentru mai putin de 2 puncte
            {
                amazon = BuildStatistics(result.Where<Price>(pr => pr.site_id == 1).ToArray<Price>());
            }
            if (result.Count<Price>(x => x.site_id == 2) >= 2)
            {
                ebay = BuildStatistics(result.Where<Price>(pr => pr.site_id == 2).ToArray<Price>());
            }

            return new StatisticsPair(amazon, ebay);
        }

        
    }
}
